MUI 有自己的樣式主題系統,tailwind 也有,為了防止之後再套用樣式的時候兩邊出現偏差,要來想辦法同步兩邊的設定。
首先建立好 MUI 的自訂主題。
// apps/ironman-nextjs/src/theme/primary.ts
'use client';
import { createTheme } from '@mui/material/styles';
const theme = createTheme({});
export default theme;
再來是引入 tailwind 的設定,理想上是直接解析 tailwind.config.js 後得到設定。
import tailwindConfig from '../../tailwind.config';
import resolveConfig from 'tailwindcss/resolveConfig';
const tailwindTheme = resolveConfig(tailwindConfig);
但因為現在是 NX 結構,tailwind.config.js 裡的 createGlobPatternsForDependencies
在打包過程中會有無法解析的狀況,所以沒法直接用,只好退而求其次。
// apps/ironman-nextjs/src/theme/primary.ts
'use client';
import { createTheme } from '@mui/material/styles';
import resolveConfig from 'tailwindcss/resolveConfig';
import tailwindColors from 'tailwindcss/colors';
import { Config } from 'tailwindcss';
export const tailwindTheme: Config['theme'] = {
extend: {
colors: {
primary: tailwindColors.blue,
},
},
};
const tailwindConfig = resolveConfig({
content: [],
theme: tailwindTheme,
});
const primary = createTheme({});
export default primary;
改成在外部制定 tailwind theme ,並引用到兩邊的設定上。
// apps/ironman-nextjs/tailwind.config.js
/** @type {import('tailwindcss').Config} */
const { createGlobPatternsForDependencies } = require('@nx/react/tailwind');
const { join } = require('path');
const { tailwindTheme } = require('./src/theme/primary'); // 引用過來
module.exports = {
content: [
join(
__dirname,
'{src,pages,components,app}/**/*!(*.stories|*.spec).{ts,tsx,html}'
),
...createGlobPatternsForDependencies(__dirname),
],
theme: tailwindTheme,
important: '#__next',
plugins: [],
corePlugins: {
preflight: false,
},
};
這樣就能用 tailwind 的樣式設定來複寫 MUI 的預設樣式,達成同步的效果。
// apps/ironman-nextjs/src/theme/primary.ts
'use client';
import { createTheme } from '@mui/material/styles';
import resolveConfig from 'tailwindcss/resolveConfig';
import tailwindColors from 'tailwindcss/colors';
import { Config } from 'tailwindcss';
import { KeyValuePair } from 'tailwindcss/types/config';
export const tailwindTheme: Config['theme'] = {
extend: {
colors: {
primary: tailwindColors.blue, // 追加顏色設定
},
},
};
const tailwindConfig = resolveConfig({
content: [],
theme: tailwindTheme,
});
const primary = createTheme({
palette: {
// 引用 tailwind 設定
primary: {
main: (
tailwindConfig.theme?.colors?.primary as KeyValuePair<number, string>
)[500],
light: (
tailwindConfig.theme?.colors?.primary as KeyValuePair<number, string>
)[300],
dark: (
tailwindConfig.theme?.colors?.primary as KeyValuePair<number, string>
)[700],
},
},
});
export default primary;
// apps/ironman-nextjs/src/theme/primary.ts
'use client';
import { createTheme } from '@mui/material/styles';
import resolveConfig from 'tailwindcss/resolveConfig';
import tailwindColors from 'tailwindcss/colors';
import { Config } from 'tailwindcss';
import { KeyValuePair } from 'tailwindcss/types/config';
export const tailwindTheme: Config['theme'] = {
extend: {
colors: {
success: tailwindColors.green, // 添加顏色設定
},
},
};
const tailwindConfig = resolveConfig({
content: [],
theme: tailwindTheme,
});
const primary = createTheme({
palette: {
// 引入 tailwind 顏色
success: {
main: (
tailwindConfig.theme?.colors?.success as KeyValuePair<number, string>
)[500],
light: (
tailwindConfig.theme?.colors?.success as KeyValuePair<number, string>
)[300],
dark: (
tailwindConfig.theme?.colors?.success as KeyValuePair<number, string>
)[700],
},
},
});
export default primary;
這樣將 theme 套用到 app 之後,不管用 MUI 的樣式寫法或是 tailwind ,產生的顏色都是相同的。
// MUI 改局部樣式的方式
<Button
variant="contained"
sx={{
bgcolor: 'success.main',
'&:hover': {
bgcolor: 'success.dark',
},
}}
>
Success
</Button>
// tailwind 方式
<Button
variant="contained"
className="bg-success-500 hover:bg-success-700"
>
Success
</Button>
不過基本上來說還是盡可能用 tailwind 排版跟改樣式,只是當有想要全局變更 MUI 的基礎樣式的時候,可以用 tailwind 的樣式來設定,避免產生誤差。